﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Security.Principal;
using System.Web.Routing;

namespace HelloMVC.Service.Infrastructure
{
    [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, Inherited = true, AllowMultiple = true)]
    public class CustomAuthorizeAttribute : FilterAttribute, IAuthorizationFilter
    {
        // Fields
        private string _roles;
        private readonly object _typeId = new object();
        private string _users;

        // Methods
        protected virtual bool AuthorizeCore(HttpContextBase httpContext)
        {
            if (httpContext == null)
            {
                throw new ArgumentNullException("httpContext");
            }
            IPrincipal user = httpContext.User;

            if (!user.Identity.IsAuthenticated)
            {
                return false;
            }

            // for this lab, we will always return fase
            return true;
        }

        private void CacheValidateHandler(HttpContext context, object data, ref HttpValidationStatus validationStatus)
        {
            validationStatus = this.OnCacheAuthorization(new HttpContextWrapper(context));
        }

        protected virtual void HandleUnauthorizedRequest(AuthorizationContext filterContext)
        {

            filterContext.Result = new HttpUnauthorizedResult();           
        }

        public virtual void OnAuthorization(AuthorizationContext filterContext)
        {
            if (filterContext == null)
            {
                throw new ArgumentNullException("filterContext");
            }
            if (this.AuthorizeCore(filterContext.HttpContext))
            {
                HttpCachePolicyBase cache = filterContext.HttpContext.Response.Cache;
                cache.SetProxyMaxAge(new TimeSpan(0L));
                cache.AddValidationCallback(new HttpCacheValidateHandler(this.CacheValidateHandler), null);
            }
            else
            {
                this.HandleUnauthorizedRequest(filterContext);
            }
        }

        protected virtual HttpValidationStatus OnCacheAuthorization(HttpContextBase httpContext)
        {
            if (httpContext == null)
            {
                throw new ArgumentNullException("httpContext");
            }
            if (!this.AuthorizeCore(httpContext))
            {
                return HttpValidationStatus.IgnoreThisRequest;
            }
            return HttpValidationStatus.Valid;
        }


        // Properties
        public string Roles
        {
            get
            {
                return (this._roles ?? string.Empty);
            }
            set
            {
                this._roles = value;
            }
        }

        public override object TypeId
        {
            get
            {
                return this._typeId;
            }
        }

        public string Users
        {
            get
            {
                return (this._users ?? string.Empty);
            }
            set
            {
                this._users = value;
            }
        }
    }

}
